package inference;

import static model.ModelUtils.getAllLeaves;
import static model.ModelUtils.getTreeAsString;
import static model.ModelUtils.resetNodesState;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import model.Interrogator;
import model.TreeNode;

import org.xml.sax.SAXException;

import parser.XMLHandler;

public class InferenceMachine {

	public static TreeNode getFirstLeafOfNodesTree(Interrogator interrogator) {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		InputStream xmlInput;
		try {
			xmlInput = new FileInputStream("tree.xml");
			SAXParser saxParser = factory.newSAXParser();
			XMLHandler xmlHandler = new XMLHandler(interrogator);
			saxParser.parse(xmlInput, xmlHandler);
			return xmlHandler.getFirstLeaf();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static TreeNode classify(TreeNode firstLeaf) {
		resetNodesState(firstLeaf);
		List<TreeNode> allLeaves = getAllLeaves(firstLeaf);
		for (TreeNode leaf : allLeaves) {
			if (leaf.check()) {
				return leaf;
			}
		}
		return null;
	}

	public static String classifyResponse(TreeNode foundLeaf) {
		if (foundLeaf == null) {
			return "I was unable to classify your element!";
		}
		return "Your element is of type: " + foundLeaf.getType()+"!";
	}

	private static void printMenu() {
		System.out.println("What would you like to do?");
		System.out.println("1.Print the tree");
		System.out.println("2.Print the rules");
		System.out.println("3.Classify a new element");
		System.out.println("4.Exit");
	}

	public static void main(String[] args) {
		BufferedReader buffer = new BufferedReader(new InputStreamReader(
				System.in));
		String line;
		int option = 0;
		TreeNode firstLeaf = getFirstLeafOfNodesTree(new ConsoleInterrogator());
		do {
			printMenu();
			try {
				line = buffer.readLine();
				if (line == null) {
					return;
				}
				option = Integer.parseInt(line.trim());
			} catch (NumberFormatException e) {
				System.out.println("Please insert a valid number!!!");
			} catch (IOException e) {
				e.printStackTrace();
			}
			switch (option) {
			case 1:
				System.out.println(getTreeAsString(firstLeaf));
				break;
			case 2:
				System.out.println(firstLeaf.getRulesAsString());
				break;
			case 3:
				System.out.println(classifyResponse(classify(firstLeaf)));
				break;
			}
		} while (option != 4);
	}

}
